package com.micro.ai.files.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.files.entity.StorageConfig;
import com.micro.ai.files.mapper.StorageConfigMapper;
import com.micro.ai.files.service.StorageConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 存储配置服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class StorageConfigServiceImpl extends ServiceImpl<StorageConfigMapper, StorageConfig> implements StorageConfigService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StorageConfig create(StorageConfig config) {
        if (config == null) {
            throw new BusinessException("F0000", "存储配置信息不能为空");
        }
        
        if (!StringUtils.hasText(config.getTenantId())) {
            throw new BusinessException("F0000", "租户ID不能为空");
        }
        
        if (!StringUtils.hasText(config.getConfigName())) {
            throw new BusinessException("F0000", "配置名称不能为空");
        }
        
        if (!StringUtils.hasText(config.getProvider())) {
            throw new BusinessException("F0000", "存储提供商不能为空");
        }
        
        // 检查同一租户下配置名称是否重复
        LambdaQueryWrapper<StorageConfig> query = new LambdaQueryWrapper<>();
        query.eq(StorageConfig::getTenantId, config.getTenantId())
             .eq(StorageConfig::getConfigName, config.getConfigName());
        
        StorageConfig existing = this.getOne(query);
        if (existing != null) {
            throw new BusinessException("F0001", "配置名称已存在: " + config.getConfigName());
        }
        
        // 如果设置为默认，需要先取消其他默认配置
        if (Boolean.TRUE.equals(config.getIsDefault())) {
            cancelOtherDefaults(config.getTenantId(), config.getProvider());
        }
        
        LocalDateTime now = LocalDateTime.now();
        config.setCreatedAt(now);
        config.setUpdatedAt(now);
        
        if (config.getStatus() == null) {
            config.setStatus("active");
        }
        
        boolean success = this.save(config);
        if (!success) {
            throw new BusinessException("F0003", "保存存储配置失败");
        }
        
        log.info("创建存储配置成功: configId={}, configName={}, provider={}", 
                config.getId(), config.getConfigName(), config.getProvider());
        return config;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StorageConfig update(String id, StorageConfig config) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "配置ID不能为空");
        }
        if (config == null) {
            throw new BusinessException("F0000", "存储配置信息不能为空");
        }
        
        StorageConfig existing = this.getById(id);
        if (existing == null) {
            throw new BusinessException("F0002", "存储配置不存在: " + id);
        }
        
        // 如果修改了配置名称，检查是否重复
        if (StringUtils.hasText(config.getConfigName()) && 
            !config.getConfigName().equals(existing.getConfigName())) {
            LambdaQueryWrapper<StorageConfig> query = new LambdaQueryWrapper<>();
            query.eq(StorageConfig::getTenantId, existing.getTenantId())
                 .eq(StorageConfig::getConfigName, config.getConfigName())
                 .ne(StorageConfig::getId, id);
            
            StorageConfig duplicate = this.getOne(query);
            if (duplicate != null) {
                throw new BusinessException("F0001", "配置名称已存在: " + config.getConfigName());
            }
        }
        
        // 如果设置为默认，需要先取消其他默认配置
        if (Boolean.TRUE.equals(config.getIsDefault())) {
            cancelOtherDefaults(existing.getTenantId(), existing.getProvider());
        }
        
        config.setId(id);
        config.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(config);
        if (!success) {
            throw new BusinessException("F0003", "更新存储配置失败");
        }
        
        log.info("更新存储配置成功: configId={}", id);
        return config;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "配置ID不能为空");
        }
        
        StorageConfig config = this.getById(id);
        if (config == null) {
            throw new BusinessException("F0002", "存储配置不存在: " + id);
        }
        
        // 注意：如果该配置正在使用中，可能需要检查是否有关联的文件
        // 这里暂时允许删除，实际业务中可能需要先检查关联关系
        
        boolean success = this.removeById(id);
        if (!success) {
            throw new BusinessException("F0003", "删除存储配置失败");
        }
        
        log.info("删除存储配置成功: configId={}, configName={}", id, config.getConfigName());
    }

    @Override
    public Page<StorageConfig> pageQuery(int pageNum, int pageSize, String tenantId, 
                                        String keyword, String provider, String status) {
        if (pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize < 1 || pageSize > 100) {
            pageSize = 20;
        }
        
        Page<StorageConfig> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<StorageConfig> query = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(tenantId)) {
            query.eq(StorageConfig::getTenantId, tenantId);
        }
        if (StringUtils.hasText(provider)) {
            query.eq(StorageConfig::getProvider, provider);
        }
        if (StringUtils.hasText(status)) {
            query.eq(StorageConfig::getStatus, status);
        }
        if (StringUtils.hasText(keyword)) {
            query.and(q -> q.like(StorageConfig::getConfigName, keyword)
                          .or().like(StorageConfig::getEndpoint, keyword)
                          .or().like(StorageConfig::getBucketName, keyword));
        }
        
        query.orderByDesc(StorageConfig::getCreatedAt);
        
        return this.page(page, query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDefault(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "配置ID不能为空");
        }
        
        StorageConfig config = this.getById(id);
        if (config == null) {
            throw new BusinessException("F0002", "存储配置不存在: " + id);
        }
        
        // 取消同一租户、同一提供商的其他默认配置
        cancelOtherDefaults(config.getTenantId(), config.getProvider());
        
        // 设置当前配置为默认
        config.setIsDefault(true);
        config.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(config);
        if (!success) {
            throw new BusinessException("F0003", "设置默认配置失败");
        }
        
        log.info("设置默认存储配置成功: configId={}, configName={}", id, config.getConfigName());
    }

    @Override
    public StorageConfig getDefaultConfig(String tenantId, String provider) {
        LambdaQueryWrapper<StorageConfig> query = new LambdaQueryWrapper<>();
        query.eq(StorageConfig::getTenantId, tenantId)
             .eq(StorageConfig::getIsDefault, true)
             .eq(StorageConfig::getStatus, "active");
        
        if (StringUtils.hasText(provider)) {
            query.eq(StorageConfig::getProvider, provider);
        }
        
        query.orderByDesc(StorageConfig::getCreatedAt)
             .last("LIMIT 1");
        
        return this.getOne(query);
    }

    /**
     * 取消其他默认配置
     */
    private void cancelOtherDefaults(String tenantId, String provider) {
        LambdaQueryWrapper<StorageConfig> query = new LambdaQueryWrapper<>();
        query.eq(StorageConfig::getTenantId, tenantId)
             .eq(StorageConfig::getProvider, provider)
             .eq(StorageConfig::getIsDefault, true);
        
        StorageConfig updateEntity = new StorageConfig();
        updateEntity.setIsDefault(false);
        updateEntity.setUpdatedAt(LocalDateTime.now());
        
        this.update(updateEntity, query);
    }
}

